package com.cxd.app.service;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.cxd.app.entity.base.InvestBase;
import com.cxd.app.entity.base.LoanBase;
import com.cxd.base.common.constants.InvestConstants;
import com.cxd.base.common.constants.LoanConstants.LoanStatus;
import com.cxd.base.common.constants.UserBillConstants.OperatorInfo;
import com.cxd.base.util.BeanTools;
import com.cxd.base.util.date.DateStyle;
import com.cxd.base.util.date.DateUtil;
import com.cxd.base.util.wtj.SUtils;
import com.cxd.message.exception.ExceedDeadlineException;
import com.cxd.message.exception.ExceedMaxAcceptableRate;
import com.cxd.message.exception.ExceedMoneyNeedRaised;
import com.cxd.message.exception.IllegalLoanStatusException;
import com.cxd.message.exception.InsufficientBalance;
import com.cxd.message.exception.NewStandardNotException;
import com.cxd.message.exception.UnreachedMoneyLimitException;

/**
 * <一句话功能简述> <功能详细描述>
 * @author wtj
 * @date 2015年12月5日 下午3:45:12
 * @company CXD
 * @version [Copyright (c) 2015 V001]
 */
@Service("investService")
public class InvestService {
	@Resource
	public BeanTools bt;
	
	@Resource
	public LoanService loanService;
	
	@Resource
	public MyAccountService myaccountService;
	
	@Resource
	public BeanService beanService;
	
	/**
	 * 保存投资项目
	 * @author wtj
	 * @date 2015年12月5日下午4:50:20
	 * @param invest
	 * @throws InsufficientBalance
	 * @throws ExceedMoneyNeedRaised
	 * @throws ExceedMaxAcceptableRate
	 * @throws ExceedDeadlineException
	 * @throws UnreachedMoneyLimitException
	 * @throws IllegalLoanStatusException
	 * @throws NewStandardNotException
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	@Transactional(propagation = Propagation.REQUIRED)  
	public void create(InvestBase invest) throws InsufficientBalance,
	ExceedMoneyNeedRaised, ExceedMaxAcceptableRate,
	ExceedDeadlineException, UnreachedMoneyLimitException, IllegalLoanStatusException,NewStandardNotException{

		String loanId = invest.getLoanId();
		invest.setInvestMoney(invest.getMoney());
		//防止并发出现
		LoanBase loan = beanService.getLoanById(loanId);
		// if (loan.getDeadline()==8 ) {
		// String hql =
		// "select count(distinct invest.loan.id) from Invest invest , Loan loan where invest.status!='cancel' and invest.loan.id = loan.id and loan.deadline=8 "+
		// "and loan.rate=0.2 and invest.user.id =?  and loan.commitTime >?";
		// List<Object> result = ht.find(hql, invest.getUser().getId(),new
		// Date());
		// if(result != null && result.get(0) != null && (Long)
		// result.get(0)>3){
		// throw new NewStandardNotException();
		// }
		// }
		//如果借款不是在筹款中，抛出异常
		if (!loan.getStatus().equals(LoanStatus.RAISING)) {
			throw new IllegalLoanStatusException(loan.getStatus());
		}

		// 判断项目尚未认购的金额，如果用户想认购的金额大于此金额，则。。。
		double remainMoney = loanService.remainMoney(loan);
		//输入的投资金额 大于 可投资的金额（尚未认购的金额） 抛出异常
		if (invest.getMoney() > remainMoney) {
			throw new ExceedMoneyNeedRaised();
		}

// 判断是否有代金券；判断能否用代金券
//		if (invest.getUserCoupon() != null) {
//			UserCouponBase userCoupon = bt.queryBean("USER_COUPON", "ID", invest.getUserCoupon(), UserCouponBase.class);
//			//代金券不是未使用状态，抛出异常
//			if (!userCoupon.getStatus().equals(CouponConstants.UserCouponStatus.UNUSED)) {
//				throw new ExceedDeadlineException();
//			}
//			// 判断代金券是否达到使用条件
//			if (invest.getMoney() < userCoupon.getCoupon()
//					.getLowerLimitMoney()) {
//				throw new UnreachedMoneyLimitException();
//			}
//			// 用户填写认购的钱数以后，判断余额，如果余额不够，不能提交，弹出新页面让用户充值
//			// investMoney>代金券金额+余额
//			if (invest.getMoney() > invest.getUserCoupon().getCoupon()
//					.getMoney()
//					+ ubs.getBalance(invest.getUser().getId())) {
//				throw new InsufficientBalance();
//			}
//			//investMoney > 可用余额，抛异常
//		} else 
		if (invest.getMoney() > myaccountService.getUserBalance(invest.getUserId())) {
			throw new InsufficientBalance();
		}

		invest.setStatus(InvestConstants.InvestStatus.BID_SUCCESS);
		invest.setRate(loan.getRate());
		invest.setTime(new Date());

		// 投资成功以后，判断项目是否有尚未认购的金额，如果没有，则更改项目状态。
		invest.setId(generateId());
		if (SUtils.isEmpty(invest.getTransferApply())) {
			invest.setTransferApply(null);
		}
		bt.add(invest);
		//处理借款募集完成
		loanService.dealRaiseComplete(loan);
		// 将金额冻结，借款项目执行时，把钱打给借款者
//		if (invest.getUserCoupon() != null) {
//			// 代金券已使用，冻结：investMoney-代金券金额
//			userCouponService.userUserCoupon(invest.getUserCoupon().getId());
//			//实际 冻结金额=investMoney-代金券
//			double realMoney = ArithUtil.sub(invest.getMoney(), invest
//					.getUserCoupon().getCoupon().getMoney());
//			if (realMoney < 0) {
//				realMoney = 0;
//			}
//			ubs.freezeMoney(invest.getUser().getId(), realMoney, OperatorInfo.INVEST_SUCCESS, "投资成功：冻结金额。借款ID:"
//					+ loan.getId() + "  投资id:" + invest.getId());
//		} else {
		myaccountService.freezeMoney(invest.getUserId(), invest.getMoney(), OperatorInfo.INVEST_SUCCESS,
					"投资成功：冻结金额。借款ID:" + loan.getId() + "  投资id:" + invest.getId());
//		}
	}
	
	public synchronized String generateId(){
		String gid = DateUtil.dateToString(new Date(), DateStyle.YYYYMMDD.getValue());
		List<InvestBase> listBase = bt.queryListBean("select ID,INTEREST,MONEY,PAID_INTEREST,PAID_MONEY,RATE,STATUS,TIME,TYPE,LOAN_ID,USER_ID, PAID_PENALTY,USER_COUPON,INVEST_MONEY,TRANSFER_APPLY , "+
				" (case IS_AUTO_INVEST WHEN 'fasel' THEN '0'  WHEN 'true' THEN '1' end)  as IS_AUTO_INVEST from INVEST im where im.id = (select max(imM.id) from Invest imM where imM.id like '"+gid+"%')", InvestBase.class);
		Integer itemp = 0;
		if (listBase.size() == 1) {
			InvestBase im = listBase.get(0);
			String temp = im.getId();
			temp = temp.substring(temp.length() - 6);
			itemp = Integer.valueOf(temp);
		}
		itemp++;
		gid += String.format("%06d", itemp);
		return gid;
	}
	/**
	 * 获取有意用户的投资记录
	 * @return
	 */
	public boolean userIsInvest(String userId) {
		String sql = "select id from Invest where status not in('cancel','wait_affirm') and user_id='" + userId + "'";
		return bt.queryListBean(sql, InvestBase.class).size() == 0? false : true;
	}
}
